package com.sxjh.config;

import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.sxjh.common.AuthException;
import com.sxjh.common.LoseEfficacyException;
import com.sxjh.common.ResultException;
import com.sxjh.entity.ConfigEntity;
import com.sxjh.entity.User;
import com.sxjh.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.AsyncHandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 权限拦截器
 */
@Component
public class AuthFilter implements AsyncHandlerInterceptor {

  private Logger logger = LoggerFactory.getLogger(AuthFilter.class);

  @Autowired
  private UserService userService;

  @Autowired
  private ConfigEntity configEntity;

  /**
   * 权限验证
   */
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    if (!configEntity.isAuth()) return true;
    if (handler != null  && handler instanceof HandlerMethod) {
      HandlerMethod handlerMethod = (HandlerMethod) handler;
      if (!handlerMethod.getMethod().isAnnotationPresent(Authorization.class)) return true;
      Object str = AnnotationUtil.getAnnotationValue(handlerMethod.getMethod(), Authorization.class);
      String token = request.getHeader("Authorization");
      if (StrUtil.isEmpty(token) || token.length() < 8) throw new ResultException("令牌不能为空");
      String token2 = token.substring(7);
      // 设置用户信息
      Integer id = null;
      try {
        id = JWT.decode(token2).getClaim("sub").asInt();
      } catch (Exception e) {
        logger.error(e.getMessage(), e);
        throw new ResultException("请输入正确的令牌格式");
      }
      if (id == null) throw new ResultException("请输入正确的令牌格式");
      User user = userService.getUser(id);
      if (user == null) throw new ResultException("没有找到用户");
      AuthContent.setUser(user);
      // 判断用户是否包含该权限
      isAuth(token, str.toString());
/*      Collection<String> permissions = user.getPermissions();
      boolean isS = CollectionUtil.contains(permissions, str.toString());
      if (!isS) throw new ResultException("没有权限");*/
    }
    return true;
  }

  public void isAuth(String token, String routeName) throws Exception{
    TimeInterval timer = DateUtil.timer();
    Integer code = null;
    String msg = null;
    try {
      HttpResponse result = HttpRequest.get(configEntity.getAddress() + "/api/javaAuth?route_name=" + routeName)
              .header("Authorization", token)
              .timeout(90000)
              .execute();
      String re = result.body();
      logger.error("请求php服务端校验权限花费时间：{}", timer.interval());
      JSONObject jsonObject = JSON.parseObject(re);
      JSONObject jsonObject1 = jsonObject.getJSONObject("status");
      code = jsonObject1.getInteger("errCode");
      msg = jsonObject1.getString("message");
      if (code == null || msg == null) throw new Exception("参数异常");
    } catch (Exception e) {
      logger.error(e.getMessage(), e);
      throw new ResultException("校验权限出错");
    }
    if (code == 10002) {
      throw new LoseEfficacyException(msg);
    }
    if (code == 10003) {
      throw new AuthException(msg);
    }
    if (code != 0) {
      throw new ResultException(msg);
    }
  }

}
